﻿using LitJson;
using System.Collections;
using UnityEngine;
using Yoozoo.External.LZ4;
using Yoozoo.Framework.Core;
using Yoozoo.Libs;
using Yoozoo.Managers.NetworkV2.DataStruct;

namespace UMT.Framework.Managers
{
    using System;
    using System.Net;
    using UnityEngine.Networking;

    public class HttpManager : Singleton<HttpManager>
    {
        public static void Get(string url,Action<string> onSuccess,Action<string> onFailure, int timeout = 10)
        {
            UnityWebRequest unityWebRequest = UnityWebRequest.Get(url);
            DownloadHandlerBuffer download = new DownloadHandlerBuffer();
            unityWebRequest.downloadHandler = download;
            unityWebRequest.timeout = timeout;

            var asyncOperation = unityWebRequest.SendWebRequest();
            asyncOperation.completed += (obj) =>
            {
                var data = download.data;
                if (asyncOperation.webRequest.isHttpError || asyncOperation.webRequest.isNetworkError)
                {
                    if (onFailure != null)
                    {
                        onFailure(asyncOperation.webRequest.error);
                    }
                }
                else
                {
                    if (onSuccess != null)
                    {
                        
                        onSuccess(asyncOperation.webRequest.downloadHandler.text);
                    }
                }
            };
        }
        
        public static void GetLuaByteArray(string url,Action<object> onSuccess,Action<string> onFailure)
        {
            using (var webClient = new WebClientPro(10 * 1000))
            {
                webClient.DownloadDataCompleted += (sender, args) =>
                {
                    if (args.Error == null && args.Result != null)
                    {
                        byte[] bytes = args.Result;
                        //onSuccess(str);
                        int offset = 0;
                        int decodeLen = Converter.GetBigEndian(BitConverter.ToInt32(bytes, offset));
                        byte[] proto = new byte[decodeLen];
                        offset += 4;
                        if (LZ4Codec.Decode(bytes, offset, bytes.Length - 4, proto, 0, decodeLen) != decodeLen)
                        {
                            Debug.LogWarning("战报数据解析出错，LZ4解析后数据长度和指定长度不一致");
                        }

                        var packet = BasicPacket.Get();
                        packet.Id = 0;
                        packet.rawData = proto;
                        onSuccess(packet);
                    }
                    else
                    {
                        onFailure(args.Error?.ToString());
                    }
                };
                webClient.DownloadDataAsync(new Uri(url));
            }
            /*UnityWebRequest unityWebRequest = UnityWebRequest.Get(url);
            DownloadHandlerBuffer download = new DownloadHandlerBuffer();
            unityWebRequest.downloadHandler = download;
            unityWebRequest.timeout = 10;
            var asyncOperation=unityWebRequest.SendWebRequest();
            asyncOperation.completed += (obj)=>
            {
                if (asyncOperation.webRequest.isHttpError || asyncOperation.webRequest.isNetworkError)
                {
                    if (onFailure!=null)
                    {
                        onFailure(asyncOperation.webRequest.error);
                    }
                }
                else
                {
                    if (onSuccess!=null)
                    {
                        var bytes = asyncOperation.webRequest.downloadHandler.data;
                        int offset = 0;
                        int decodeLen = Converter.GetBigEndian(BitConverter.ToInt32(bytes, offset));
                        byte[] proto = new byte[decodeLen];
                        offset += 4;
                        if (LZ4Codec.Decode(bytes, offset, bytes.Length - 4, proto, 0, decodeLen) != decodeLen)
                        {
                            Debug.LogWarning("战报数据解析出错，LZ4解析后数据长度和指定长度不一致");
                        }

                        var packet = BasicPacket.Get();
                        packet.Id = 0;
                        packet.rawData = proto;
                        onSuccess(packet);
                    }
                }
                asyncOperation.webRequest.Abort();
                unityWebRequest.Dispose();
            };*/
        }

        public static void Post(string url,string json, Action<string> onSuccess, Action<string> onFailure)
        {

            JsonData jsonData = JsonMapper.ToObject(json);
            WWWForm form = new WWWForm();
            IDictionary dict = jsonData as IDictionary;
            foreach (string key in dict.Keys)
            {
                form.AddField(key, dict[key].ToString());
            }
            UnityWebRequest unityWebRequest = UnityWebRequest.Post(url,form);
            var asyncOperation = unityWebRequest.SendWebRequest();
            asyncOperation.completed += (obj) =>
            {
                if (asyncOperation.webRequest.isHttpError || asyncOperation.webRequest.isNetworkError)
                {
                    if (onFailure != null)
                    {
                        onFailure(asyncOperation.webRequest.error);
                    }
                }
                else
                {
                    if (onSuccess != null)
                    {
                        onSuccess(asyncOperation.webRequest.downloadHandler.text);
                    }
                }
                asyncOperation.webRequest.Abort();
                unityWebRequest.Dispose();
            };
        }
        public static void PostJson(string url,string json,Action<string> onSuccess,Action<string> onFailure)
        {
            UnityWebRequest unityWebRequest = new UnityWebRequest(url, "POST");
            unityWebRequest.useHttpContinue = false; //需要设置该值为false，否则数据会出现不完整导致失败
            unityWebRequest.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json));
            unityWebRequest.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
            unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
            unityWebRequest.timeout = 20;
            var asyncOperation = unityWebRequest.SendWebRequest();
            asyncOperation.completed += (obj) =>
            {
                if (asyncOperation.webRequest.isHttpError || asyncOperation.webRequest.isNetworkError)
                {
                    if (onFailure != null)
                    {
                        //onFailure(asyncOperation.webRequest.error);
                        onFailure(string.Format("responseCode:{0} errorMsg:{1}",asyncOperation.webRequest.responseCode,asyncOperation.webRequest.error));
                    }
                }
                else
                {
                    if (onSuccess != null)
                    {
                        onSuccess(asyncOperation.webRequest.downloadHandler.text);
                    }
                }
                asyncOperation.webRequest.Abort();
                unityWebRequest.Dispose();
            };
        }

        public static void GetBinaryStrUseClient(string url, Action<string> onSuccess, Action<string> onFailure,
            int timeout = 10)
        {
            try
            {
                using (var webClient = new WebClientPro(timeout * 1000))
                {
                
                    webClient.DownloadDataCompleted += (sender, args) =>
                    {
                        if (args.Error == null && args.Result != null)
                        {
                            var str = System.Text.Encoding.Default.GetString(args.Result);
                            onSuccess(str);
                        }
                        else
                        {
                            onFailure(url);
                        }
                    };
                    webClient.DownloadDataAsync(new Uri(url));
                }
            }
            catch (Exception e)
            {
                onFailure($"url : {url}\n{e}");
            }
        }

        public class WebClientPro : WebClient
        {
            /// <summary>
            /// 过期时间
            /// </summary>
            public int Timeout { get; set; }

            /// <summary>
            /// 默认30秒
            /// </summary>
            /// <param name="timeout"></param>
            public WebClientPro(int timeout = 30000)
            {
                Timeout = timeout;
            }

            /// <summary>
            /// 重写GetWebRequest,添加WebRequest对象超时时间
            /// </summary>
            /// <param name="address"></param>
            /// <returns></returns>
            protected override WebRequest GetWebRequest(Uri address)
            {
                HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
                request.Timeout = Timeout;
                request.ReadWriteTimeout = Timeout;
                return request;
            }
        }
    }
}
